package com.maike.babyname.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;

import androidx.annotation.Nullable;

import com.maike.babyname.R;
import com.maike.babyname.utils.UiUtils;

import net.lucode.hackware.magicindicator.FragmentContainerHelper;
import net.lucode.hackware.magicindicator.buildins.ArgbEvaluatorHolder;
import net.lucode.hackware.magicindicator.buildins.UIUtil;
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
import net.lucode.hackware.magicindicator.buildins.commonnavigator.model.PositionData;

import java.util.Arrays;
import java.util.List;

/**
 * 项目名称：userchat
 * 类描述：
 * 创建人：wsk
 * 创建时间：2020-01-16 20:08
 * 修改人：wsk
 * 修改时间：2020-01-16 20:08
 * 修改备注：
 *
 * @author wsk
 */
public class DrawablePageIndicator extends View implements IPagerIndicator {
    public static final int MODE_MATCH_EDGE = 0;   // 直线宽度 == title宽度 - 2 * mXOffset
    public static final int MODE_WRAP_CONTENT = 1;    // 直线宽度 == title内容宽度 - 2 * mXOffset
    public static final int MODE_EXACTLY = 2;  // 直线宽度 == mLineWidth

    private int mMode;  // 默认为MODE_MATCH_EDGE模式

    // 控制动画
    private Interpolator mStartInterpolator = new LinearInterpolator();
    private Interpolator mEndInterpolator = new LinearInterpolator();

    private float mYOffset;   // 相对于底部的偏移量，如果你想让直线位于title上方，设置它即可
    private int mLineHeight;
    private float mXOffset;
    private int mLineWidth;
    private float mRoundRadius;

    private List<Integer> mColors;
    private Paint mPaint;
    private List<PositionData> mPositionDataList;
    private RectF mLineRect = new RectF();
    private LinearGradient mGradient;
    private int res;


    public DrawablePageIndicator(Context context) {
        super(context);
        init(context);
    }


    public DrawablePageIndicator(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initAttrs(attrs);
    }


    public DrawablePageIndicator(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(attrs);
    }


    private void init(Context context) {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.FILL);
        mLineHeight = UIUtil.dip2px(context, 3);
        mLineWidth = UIUtil.dip2px(context, 10);
    }


    public void setResBg(int res) {
        this.res = res;
    }



    private void initAttrs(AttributeSet attrs) {
        try {
            TypedArray t = getContext()
                    .obtainStyledAttributes(attrs, R.styleable.LinePageIndicator);
            t.recycle();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (res != 0) {
            Bitmap bitmap = UiUtils.drawableToBitmap(getContext(), mLineWidth, mLineHeight, res);
            Shader shader = new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.CLAMP);
            //mPaint.setShader(shader);
            //if (null == mGradient) {
//            mGradient = new LinearGradient(mLineRect.left, mLineRect.top, mLineRect.right, mLineRect.bottom, startColor, endColor, Shader.TileMode.CLAMP);
            //mGradient = new LinearGradient(0, 0, mLineRect.right/2, 0,
            //        new int[]{startColor,endColor}, new float[]{0,0.5f}, Shader.TileMode.CLAMP);
            //}
            mPaint.setShader(shader);
            canvas.drawRoundRect(mLineRect, mRoundRadius, mRoundRadius, mPaint);
        } else {
            canvas.drawRoundRect(mLineRect, mRoundRadius, mRoundRadius, mPaint);
        }
    }


    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (mPositionDataList == null || mPositionDataList.isEmpty()) {
            return;
        }

//         计算颜色
        if (mColors != null && mColors.size() > 0) {
            int currentColor = mColors.get(Math.abs(position) % mColors.size());
            int nextColor = mColors.get(Math.abs(position + 1) % mColors.size());
            int color = ArgbEvaluatorHolder.eval(positionOffset, currentColor, nextColor);
            mPaint.setColor(color);
        }

        // 计算锚点位置
        PositionData current = FragmentContainerHelper
                .getImitativePositionData(mPositionDataList, position);
        PositionData next = FragmentContainerHelper
                .getImitativePositionData(mPositionDataList, position + 1);

        float leftX;
        float nextLeftX;
        float rightX;
        float nextRightX;
        if (mMode == MODE_MATCH_EDGE) {
            leftX = current.mLeft + mXOffset;
            nextLeftX = next.mLeft + mXOffset;
            rightX = current.mRight - mXOffset;
            nextRightX = next.mRight - mXOffset;
        } else if (mMode == MODE_WRAP_CONTENT) {
            leftX = current.mContentLeft + mXOffset;
            nextLeftX = next.mContentLeft + mXOffset;
            rightX = current.mContentRight - mXOffset;
            nextRightX = next.mContentRight - mXOffset;
        } else {    // MODE_EXACTLY
            leftX = current.mLeft + (current.width() - mLineWidth) / 2;
            nextLeftX = next.mLeft + (next.width() - mLineWidth) / 2;
            rightX = current.mLeft + (current.width() + mLineWidth) / 2;
            nextRightX = next.mLeft + (next.width() + mLineWidth) / 2;
        }

        mLineRect.left = leftX +
                (nextLeftX - leftX) * mStartInterpolator.getInterpolation(positionOffset);
        mLineRect.right = rightX +
                (nextRightX - rightX) * mEndInterpolator.getInterpolation(positionOffset);
        mLineRect.top = getHeight() - mLineHeight - mYOffset;
        mLineRect.bottom = getHeight() - mYOffset;

        invalidate();
    }


    @Override
    public void onPageSelected(int position) {

    }


    @Override
    public void onPageScrollStateChanged(int state) {

    }


    @Override
    public void onPositionDataProvide(List<PositionData> dataList) {
        mPositionDataList = dataList;
    }


    public float getYOffset() {
        return mYOffset;
    }


    public void setYOffset(float yOffset) {
        mYOffset = yOffset;
    }


    public float getXOffset() {
        return mXOffset;
    }


    public void setXOffset(float xOffset) {
        mXOffset = xOffset;
    }


    public float getLineHeight() {
        return mLineHeight;
    }


    public void setLineHeight(int lineHeight) {
        mLineHeight = lineHeight;
    }


    public float getLineWidth() {
        return mLineWidth;
    }


    public void setLineWidth(int lineWidth) {
        mLineWidth = lineWidth;
    }


    public float getRoundRadius() {
        return mRoundRadius;
    }


    public void setRoundRadius(float roundRadius) {
        mRoundRadius = roundRadius;
    }


    public int getMode() {
        return mMode;
    }


    public void setMode(int mode) {
        if (mode == MODE_EXACTLY || mode == MODE_MATCH_EDGE || mode == MODE_WRAP_CONTENT) {
            mMode = mode;
        } else {
            throw new IllegalArgumentException("mode " + mode + " not supported.");
        }
    }


    public Paint getPaint() {
        return mPaint;
    }


    public List<Integer> getColors() {
        return mColors;
    }


    public void setColors(Integer... colors) {
        mColors = Arrays.asList(colors);
    }


    public Interpolator getStartInterpolator() {
        return mStartInterpolator;
    }


    public void setStartInterpolator(Interpolator startInterpolator) {
        mStartInterpolator = startInterpolator;
        if (mStartInterpolator == null) {
            mStartInterpolator = new LinearInterpolator();
        }
    }


    public Interpolator getEndInterpolator() {
        return mEndInterpolator;
    }


    public void setEndInterpolator(Interpolator endInterpolator) {
        mEndInterpolator = endInterpolator;
        if (mEndInterpolator == null) {
            mEndInterpolator = new LinearInterpolator();
        }
    }
}
